
servicesModule.service('statsModel', function($http, $q, statsViewerSession) {

    // result
    var accountStatistics;
    var statsPeriodsPool;

    function getStatisticsImpl() {

        if (accountStatistics != null) {

            log("Returning cached statistics");

            // if statistics if has already been loaded and cached,
            // return promise that resolves immediately

            var deferred = $q.defer();

            // construct statsModelState object
            deferred.resolve({
                accountStatistics: accountStatistics,
                statsPeriodsPool: statsPeriodsPool,
                httpElapsed: 0
            });

            return deferred.promise;

        } else {
            return loadStatisticsFromServer();
        }
    }

    function loadStatisticsFromServer() {

        var httpElapser = new Elapser();

        var deferred = $q.defer();

        accountStatistics = null;
        statsPeriodsPool = null;

        var criteria = statsViewerSession.criteria;

        $http(
            {
                method: 'GET',
                url: "/api/statistics/" + criteria.clientName + "/" + criteria.accountId,
                params: {
                    "metric-names": criteria.metricNames,
                    "start-date": criteria.startDate,
                    "end-date": criteria.endDate,
                    t: new Date().getTime()
                }
            })
            .success(function(data, status, headers, config) {

                log("$http successful, " + httpElapser);

                var statisticsPool = data.statisticsPool;
                accountStatistics = statisticsPool.accounts[0];

                var statsPeriods = statisticsPool.statsPeriods;
                statsPeriodsPool = new StatsPeriodsPool(statsPeriods);

                // construct statsModelState object
                deferred.resolve({
                    accountStatistics: accountStatistics,
                    statsPeriodsPool: statsPeriodsPool,
                    httpElapsed: httpElapser.getElapsed()
                });

            })
            .error(function(data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.

                log("$http failed, " + httpElapser);

                deferred.reject({
                    errorData: data,
                    httpElapsed: httpElapser.getElapsed()
                });
            });

        return deferred.promise;
    }

    return {

        // Always returns promise
        // This promise resolves immediately if statistics has already been loaded and cached
        getStatistics: function() {
            return getStatisticsImpl();
        },

        getHttpElapsed: function() {
            return httpElapsed;
        },

        toString: function() {
            return "statsViewer Stats Model";
        }
    }
});